'	CryptographyHelper & Cryptography .NET classes
'	http://maxvergelli.wordpress.com/

'	Copyright (c) 2010 Max Vergelli

'	Permission is hereby granted, free of charge, to any person obtaining a copy
'	of this software and associated documentation files (the "Software"), to deal
'	in the Software without restriction, including without limitation the rights
'	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
'	copies of the Software, and to permit persons to whom the Software is
'	furnished to do so, subject to the following conditions:

'	The above copyright notice and this permission notice shall be included in
'	all copies or substantial portions of the Software.

'	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
'	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
'	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
'	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
'	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
'	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
'	THE SOFTWARE.


' HOW TO USE IT HOW TO USE IT HOW TO USE IT

'Dim cryptoHelper As New CryptographyHelper

''select your favorite encoding type of the output (note that hexadecimal result is longer then base64 compression)
'cryptoHelper.EncodingType = CryptographyHelper.EncodingBaseTypes.Hex 'CryptographyHelper.EncodingBaseTypes.Base64

'Dim password As String = "my secret password to encrypt or decrypt strings"
'Dim encryptedText As String = cryptoHelper.Encrypt("plain text to encrypt...", password)
'Dim decryptedText As String = cryptoHelper.Decrypt(encryptedText, password)

''if you want get an hash of a string try out one of the following...
'Dim MD5hash As String = cryptoHelper.GetHash("string to hash", CryptographyHelper.HashTypes.MD5)
'Dim SHA1hash As String = cryptoHelper.GetHash("string to hash", CryptographyHelper.HashTypes.SHA1)
'Dim SHA256hash As String = cryptoHelper.GetHash("string to hash", CryptographyHelper.HashTypes.SHA256)

' HOW TO USE IT HOW TO USE IT HOW TO USE IT

Imports System.IO
Imports System.Text
Imports System.Security.Cryptography
Namespace Utils
    Public Class Cryptography
        Private strKey As String = Nothing
        Private bytKey() As Byte = Nothing
        Private textConverter As New UnicodeEncoding()
        Private rijndael As New RijndaelManaged() '"rèin-daal" <IMG class=wp-smiley alt=:) src="http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif?m=1305841840g"> 

        Public Sub New(Optional ByVal encryption_key As String = "")
            If encryption_key <> "" Then EncryptionKey = encryption_key
        End Sub


        'OutstandingIssue: Pkoi Aleblanc
        Protected Overrides Sub Finalize()
            If textConverter IsNot Nothing Then
                textConverter = Nothing
            End If
            If rijndael IsNot Nothing Then
                rijndael = Nothing
            End If
            strKey = Nothing
            bytKey = Nothing
        End Sub

        Public Property EncryptionKey() As String
            Get
                Return strKey
            End Get
            Set(ByVal Value As String)
                Try
                    'Set the key string
                    strKey = Value
                    'Set hash in bytes of the key string
                    Dim hash256 As New SHA256Managed()
                    bytKey = hash256.ComputeHash(textConverter.GetBytes(strKey))
                    hash256 = Nothing
                    If UBound(bytKey) < 0 Then Exit Property
                    'Set Rijndael Key and IV vector for 256 bit encryption
                    Dim MainKey(31) As Byte
                    Dim MainIV(15) As Byte
                    Dim iDiffBlock As Integer = 5
                    rijndael.KeySize = 256 'bit
                    Dim n As Integer = 0
                    Dim x As Integer = 0
                    Dim y As Integer = 0
                    For n = 0 To UBound(MainKey)
                        MainKey(n) = bytKey(x)
                        If n > iDiffBlock And n <= UBound(MainIV) + iDiffBlock Then
                            MainIV(y) = bytKey(x)
                            y = y + 1
                        End If
                        x = x + 1
                        If x > UBound(bytKey) Then x = 0
                    Next
                    rijndael.Key = MainKey
                    rijndael.IV = MainIV
                Catch
                    'set a blank encryption key then we cannot encrypt/decrypt
                    strKey = Nothing
                End Try
            End Set
        End Property

        Public Function Encrypt(ByVal clear_text As String) As Byte()
            Dim enc_bytes() As Byte = Nothing
            If strKey IsNot Nothing Then
                'get byte array from text
                Dim bytes() As Byte = textConverter.GetBytes(clear_text)
                'encrypt data
                Dim encryptor As ICryptoTransform = rijndael.CreateEncryptor()
                Dim msEncrypt As New MemoryStream()
                Dim csEncrypt As New CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)
                'write all data to the crypto stream and flush it
                csEncrypt.Write(bytes, 0, bytes.Length)
                csEncrypt.FlushFinalBlock()
                'get encrypted byte array
                enc_bytes = msEncrypt.ToArray()
                msEncrypt.Dispose()
                csEncrypt.Dispose()
            End If
            Return enc_bytes
        End Function

        Public Function Decrypt(ByVal encrypted_text As Byte()) As String
            Dim dec_text As String = Nothing
            If strKey IsNot Nothing Then
                Dim decryptor As ICryptoTransform = rijndael.CreateDecryptor()
                Dim msDecrypt As New MemoryStream(encrypted_text)
                Dim csDecrypt As New CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)
                'prepare buffer
                Dim bytes() As Byte = New Byte(encrypted_text.Length - 1) {}
                'read the data out of the crypto stream
                csDecrypt.Read(bytes, 0, bytes.Length)
                'convert the byte array back into a string
                dec_text = textConverter.GetString(bytes)
                'strip null end chars
                StripEndNull(dec_text)
                msDecrypt.Dispose()
                csDecrypt.Dispose()
            End If
            Return dec_text
        End Function

        Public Function BytesToBase64(ByVal input_bytes As Byte()) As String
            Dim s As String = Nothing
            s = Convert.ToBase64String(input_bytes)
            Return s
        End Function

        Public Function Base64ToBytes(ByVal input_base64 As String) As Byte()
            Dim b() As Byte = Nothing
            b = Convert.FromBase64String(input_base64)
            Return b
        End Function

        Public Function BytesToHexString(ByVal input_bytes As Byte()) As String
            Dim s As String = Nothing
            'Dim s As String = BitConverter.ToString(input_bytes).Replace("-", String.Empty)
            Dim builder As New StringBuilder()
            For i As Integer = 0 To input_bytes.Length - 1
                builder.AppendFormat("{0:x2}", input_bytes(i))
            Next
            s = builder.ToString()
            builder = Nothing
            Return s
        End Function

        Public Function HexStringToBytes(ByVal input_hex_string As String) As Byte()
            Dim bytes As Byte() = Nothing
            'i variable used to hold position in string
            Dim i As Integer = 0
            'x variable used to hold byte array element position
            Dim x As Integer = 0
            'allocate byte array based on half of string length
            bytes = New Byte((input_hex_string.Length) \ 2 - 1) {}
            'loop through the string - 2 bytes at a time converting
            'it to decimal equivalent and store in byte array
            While input_hex_string.Length > i + 1
                Dim lngDecimal As Long = Convert.ToInt32(input_hex_string.Substring(i, 2), 16)
                bytes(x) = Convert.ToByte(lngDecimal)
                i = i + 2
                x += 1
            End While
            'return the finished byte array of decimal values
            Return bytes
        End Function

        Public Function CreateMD5Hash(ByVal input As String) As Byte()
            Dim hash As Byte() = Nothing
            Dim bytes() As Byte = textConverter.GetBytes(input)
            Dim MD5 As New MD5CryptoServiceProvider()
            hash = MD5.ComputeHash(bytes)
            MD5 = Nothing
            Return hash
        End Function

        Public Function CreateSHA1Hash(ByVal input As String) As Byte()
            Dim hash As Byte() = Nothing
            Dim bytes() As Byte = textConverter.GetBytes(input)
            Dim SHA As New SHA1CryptoServiceProvider()
            hash = SHA.ComputeHash(bytes)
            SHA = Nothing
            Return hash
        End Function

        Public Function CreateSHA256Hash(ByVal input As String) As Byte()
            Dim hash As Byte() = Nothing
            Dim bytes() As Byte = textConverter.GetBytes(input)
            Dim SHA As New SHA256CryptoServiceProvider()
            hash = SHA.ComputeHash(bytes)
            SHA = Nothing
            Return hash
        End Function

        Public Function CreateSHA512Hash(ByVal input As String) As Byte()
            Dim hash As Byte() = Nothing
            Dim bytes() As Byte = textConverter.GetBytes(input)
            Dim SHA As New SHA512CryptoServiceProvider()
            hash = SHA.ComputeHash(bytes)
            SHA = Nothing
            Return hash
        End Function

        Private Sub StripEndNull(ByRef input_string As String)
            Dim nullchar As Char = Convert.ToChar(0) '&H0
            If input_string.Length > 0 And input_string.EndsWith(nullchar.ToString) Then
                Dim n As Integer
                For n = input_string.Length - 1 To 0 Step -1
                    If input_string.Chars(n) <> nullchar Then
                        input_string = input_string.Substring(0, n + 1)
                        Exit For
                    End If
                Next
            End If
            Convert.ToString(input_string)
        End Sub
    End Class
End Namespace